<script setup>
import {
  GetMenuListAPI,
  deptTreeSelect,
  GetViewAPI,
  GetListAPI,
  AddDataAPI,
  EditDataAPI,
  DelDataAPI,
  UpdateStatusAPI,
  dataScopeSApi,
} from "@/api/system/role";

import {
  roleMenuTreeselect,
  treeselect as menuTreeselect,
} from "@/api/system/menu";

const { proxy } = getCurrentInstance();
const router = useRouter();

const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
// 单据类别
const receiptAuthority = ref([
  { label: "全部单据", value: 1 },
  { label: "个人单据", value: 2 },
]);

// 表单ref
const addFormRef = ref(null);

// 数据范围选项
const dataScopeOptions = ref([
  { value: "1", label: "全部数据权限" },
  { value: "2", label: "自定数据权限" },
  { value: "3", label: "本部门数据权限" },
  { value: "4", label: "本部门及以下数据权限" },
  { value: "5", label: "仅本人数据权限" },
]);

// 菜单权限ref
const menuRef = ref(null);

// 部门权限ref
const deptRef = ref(null);

// 列表数据
const tableData = ref([]);

// 部门数据
const deptOptions = ref([]);

// 菜单权限
const menuList = ref([]);

// 按钮枚举
const buttonList = ref([]);

// 状态 参数...
const state = reactive({
  openDataScope: false,
  singleDis: false, // 多选后禁用
  multipleDis: false, // 没有选择后禁用
  loading: false, // 列表加载状态
  btnLoading: false, // 按钮加载状态
  isShow: false, // 弹窗状态
  title: "新增", // 弹窗标题
  total: 0, // 列表总量
  ids: "", // 列表选择的id
});

// 查询条件
const query = reactive({
  pageNum: 1,
  pageSize: 10,
});

// 查询条件 枚举
const selectList = ref([
  // { type: '日期范围' },
  { label: "状态", model: "status", type: "下拉单选", opt: sys_normal_disable },
  { label: "角色名称", model: "roleName", type: "输入框" },
]);

// 列表枚举
const column = ref([
  // {
  //   label: "角色编号",
  //   prop: "roleId",
  // },
  {
    label: "角色名称",
    prop: "roleName",
  },
  {
    label: "角色描述",
    prop: "remark",
  },
  {
    label: "状态",
    prop: "status",
  },

  {
    label: "创建人",
    prop: "createBy",
  },
  {
    label: "创建时间",
    prop: "createTime",
  },
  {
    label: "操作",
    prop: "x",
    width: "320px",
  },
]);

// 表单字段
const addForm = reactive({
  remark: "",
  roleKey: "",
  roleName: "",
  status: 0,
  menuIds: [],
});

// 表单校验
const rules = reactive({
  roleName: [{ required: true, message: "请填写角色名称", trigger: "blur" }],
  receiptAuthority: [
    { required: true, message: "请选择单据权限", trigger: "change" },
  ],
  menuIdListArr: [
    { required: true, message: "请选择菜单权限", trigger: "change" },
  ],
  wareHouseIdListArr: [
    { required: true, message: "请选择操作仓库", trigger: "change" },
  ],
  roleKey: [{ required: true, message: "请填写权限字符", trigger: "blur" }],
});

// 初始化按钮 原因：没有办法做到完全响应 每次事件触发再次执行
const initBtn = () => {
  buttonList.value = [{ type: "add", hasPermi: "system:role:add" }];
};

// 新增弹窗
const addDic = () => {
  getmenuList();

  state.isShow = true;
  state.title = "新增";
};

/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeselect(roleId) {
  return roleMenuTreeselect(roleId).then((response) => {
    menuOptions.value = response.menus;
    return response;
  });
}

// 修改弹窗
const editDic = async (val) => {
  getmenuList();
  proxy.loading("请求中,请稍后");
  try {
    const { data: result } = await GetViewAPI(val.roleId);
    Object.keys(result).forEach((t) => (addForm[t] = result[t]));
    state.isShow = true;
    nextTick(() => {
      menuRef.value.setCheckedKeys(addForm.menuIds, true);
      addForm.menuIds.forEach((v) => {
        nextTick(() => {
          menuRef.value.setChecked(v, true, false);
        });
      });
    });
    state.title = "修改";
  } catch {
  } finally {
    proxy.closeLoading();
  }
};

// 查看弹窗
const lookDic = async (val) => {
  try {
    console.log("---");

    const { data: result } = await GetViewAPI(val.roleId);
    Object.keys(result).forEach((t) => (addForm[t] = result[t]));
    state.title = "查看";
    state.isShow = true;
  } catch {
  } finally {
    proxy.closeLoading();
  }
};

// 数据权限
const auth = async (val) => {
  proxy.loading("请求中,请稍后");

  try {
    getDeptTree(val.roleId);
    const { data: result } = await GetViewAPI(val.roleId);
    Object.keys(result).forEach((t) => (addForm[t] = result[t]));
    state.openDataScope = true;

    nextTick(() => {
      addForm.menuIds.forEach((v) => {
        nextTick(() => {
          deptRef.value.setChecked(v, true, false);
        });
      });
    });
    state.title = "数据权限";
  } catch {
  } finally {
    proxy.closeLoading();
  }

  console.log("数据权限");
};

/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
  // 目前被选中的菜单节点
  let checkedKeys = menuRef.value.getCheckedKeys();
  // 半选中的菜单节点
  let halfCheckedKeys = menuRef.value.getHalfCheckedKeys();
  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
  return checkedKeys;
}

// 新增提交
const addSub = async () => {
  const result = await addFormRef.value.validate();
  if (!result) return;
  addForm.menuIds = getMenuAllCheckedKeys();
  try {
    state.btnLoading = true;
    await AddDataAPI(addForm);
    proxy.successMsg("新增成功!");
    state.isShow = false;
    getList();
  } catch {
  } finally {
    state.btnLoading = false;
  }
};

// 修改提交
const editSub = async () => {
  const result = await addFormRef.value.validate();
  if (!result) return;
  addForm.menuIds = getMenuAllCheckedKeys();

  try {
    state.btnLoading = true;
    delete addForm.status;
    await EditDataAPI(addForm);
    proxy.successMsg("修改成功!");
    state.isShow = false;
    getList();
  } catch {
  } finally {
    state.btnLoading = false;
  }
};

// 删除
const remove = async (id) => {
  const is = await proxy.DelMessageBox();
  if (!is) return;
  await DelDataAPI(id);
  proxy.successMsg("删除成功!");
  getList();
};

// 启用状态改变时
const switchChange = async (val) => {
  const result = await proxy.MessageBox(
    `是否修改状态为${val.status == 0 ? "不启用" : "启用"}?`
  );
  if (!result) {
    val.status == 1 ? (val.status = 0) : (val.status = 1);
    return;
  }
  try {
    await UpdateStatusAPI({
      roleId: val.roleId,
      status: val.status,
    });
    proxy.successMsg("修改成功!");
    getList();
  } catch {
    val.status == 1 ? (val.status = 0) : (val.status = 1);
  } finally {
  }
};

// 弹窗关闭时
const close = () => {
  Object.keys(addForm).forEach((t) => (addForm[t] = ""));
  addForm.menuIdList = [];
  addForm.deptIds = [];
};

// 列表选中 及 判断是否禁用删除 || 修改
const handleSelectionChange = ({ ids, row }) => {
  state.ids = ids;
  state.multipleDis = !row.length;
  state.singleDis = row.length != 1;
  initBtn();
};
handleSelectionChange({ ids: [], row: [] });

// 查询条件
const selectSubmit = (val) => {
  Object.keys(val).forEach((t) => (query[t] = val[t]));
  getList();
};

// 获取列表
const getList = async () => {
  state.loading = true;
  try {
    const { data: result } = await GetListAPI(query);
    tableData.value = result.result;
    state.total = result.total;
  } catch {
  } finally {
    state.loading = false;
  }
};

/** 树权限（展开/折叠）*/
const handleCheckedTreeExpand = (value, type) => {
  if (type == "menu") {
    let treeList = menuList.value;
    for (let i = 0; i < treeList.length; i++) {
      menuRef.value.store.nodesMap[treeList[i].menuId].expanded = value;
    }
  } else if (type == "dept") {
    let treeList = deptOptions.value;
    for (let i = 0; i < treeList.length; i++) {
      deptRef.value.store.nodesMap[treeList[i].id].expanded = value;
    }
  }
};

/** 树权限（全选/全不选） */
const handleCheckedTreeNodeAll = (value, type) => {
  if (type == "menu") {
    menuRef.value.setCheckedNodes(value ? menuList.value : []);
  } else if (type == "dept") {
    deptRef.value.setCheckedNodes(value ? deptOptions.value : []);
  }
};

/** 树权限（父子联动） */
const handleCheckedTreeConnect = (value, type) => {
  if (type == "menu") {
    addForm.menuCheckStrictly = value ? true : false;
  } else if (type == "dept") {
    addForm.deptCheckStrictly = value ? true : false;
  }
};

// 获取菜单数据
const getmenuList = async () => {
  const result = await GetMenuListAPI();
  menuList.value = proxy.handleTree(result.data, "menuId");
};

// 根据角色ID查询部门树结构
const getDeptTree = async (roleId) => {
  const response = await deptTreeSelect(roleId);
  deptOptions.value = response.depts;
  return response;
};

// 数据权限分配保存
const submitDataScope = async () => {
  try {
    state.btnLoading = true;
    if (deptRef.value.getCheckedKeys()) {
      addForm.menuIds = deptRef.value.getCheckedKeys();
    }
    await dataScopeSApi(addForm);
    proxy.successMsg("权限修改成功!");
    state.isShow = false;
    close();
    getList();
  } catch {
  } finally {
    state.btnLoading = false;
  }
};

getList();

// getDeptTree()
</script>

<template>
  <div class="app-container">
    <!-- 查询条件组件 -->
    <p-select-form :selectForm="selectList" @selectSubmit="selectSubmit" />
    <el-card class="box-card">
      <!-- 按钮组件 -->

      <!-- 表格数据 -->
      <p-table
        keyId="roleId"
        :isSel="false"
        :loading="state.loading"
        :data="tableData"
        :column="column"
        :total="state.total"
        v-model:page="query.pageNum"
        v-model:limit="query.pageSize"
        @change="handleSelectionChange"
        @pagination="getList"
      >
        <template #buttons>
          <p-button :list="buttonList" @add="addDic" @remove="remove"
        /></template>
        <template #columnCell="{ column, record }">
          <p-switch
            active="0"
            inactive="1"
            v-if="column.prop == 'status'"
            v-model="record.status"
            :disabled="record.noC"
            @change="switchChange(record)"
          />
          <p-operate
            v-if="column.prop == 'x'"
            :list="[
              {
                icon: 'Edit',
                emit: 'edit',
                disabled: record.noE,
                text: '修改',
                type: 'primary',
                hasPermi: 'system:role:edit',
              },
              {
                icon: 'Cpu',
                emit: 'distribution',
                disabled: false,
                text: '分配用户',
                type: 'primary',
                hasPermi: 'system:role:assigneUser',
              },
              // {
              //   icon: 'Promotion',
              //   emit: 'auth',
              //   disabled: false,
              //   text: '数据权限',
              //   type: 'primary',
              //   hasPermi: 'system:role:dataPermisse',
              // },
              {
                icon: 'DeleteFilled',
                emit: 'remove',
                disabled: record.noD,
                text: '删除',
                type: 'danger',
                hasPermi: 'system:role:remove',
              },
            ]"
            @remove="remove(record.roleId)"
            @edit="editDic(record)"
            @look="lookDic(record)"
            @distribution="
              router.push('/system/role-auth/user/' + record.roleId)
            "
            @auth="auth(record)"
          />
        </template>
      </p-table>
    </el-card>
    <!-- 新增弹窗 -->
    <p-dialog
      v-model="state.isShow"
      :title="state.title"
      :loading="state.btnLoading"
      @ok="state.title == '新增' ? addSub() : editSub()"
      @close="close"
      width="50rem"
    >
      <!--   inline -->
      <el-form
        ref="addFormRef"
        :model="addForm"
        inline
        :rules="rules"
        label-width="120px"
        status-icon
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input
            clearable
            v-model="addForm.roleName"
            placeholder="请输入角色名称"
          />
        </el-form-item>
        <el-form-item prop="roleKey">
          <template #label>
            <span>
              <el-tooltip
                content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasRole('admin')`)"
                placement="top"
              >
                <el-icon><question-filled /></el-icon>
              </el-tooltip>
              权限字符
            </span>
          </template>
          <el-input
            clearable
            v-model="addForm.roleKey"
            placeholder="请输入权限字符"
          />
        </el-form-item>
        <div>
          <el-form-item label="菜单权限">
            <div class="flex">
              <el-checkbox
                v-model="addForm.menuExpand"
                @change="handleCheckedTreeExpand($event, 'menu')"
                >展开/折叠</el-checkbox
              >
              <el-checkbox
                v-model="addForm.menuNodeAll"
                @change="handleCheckedTreeNodeAll($event, 'menu')"
                >全选/全不选</el-checkbox
              >
              <el-checkbox
                v-model="addForm.menuCheckStrictly"
                @change="handleCheckedTreeConnect($event, 'menu')"
                >父子联动</el-checkbox
              >
            </div>
            <el-tree
              class="tree-border"
              :data="menuList"
              show-checkbox
              ref="menuRef"
              node-key="menuId"
              :check-strictly="!addForm.menuCheckStrictly"
              empty-text="加载中，请稍候"
              :props="{
                label: 'menuName',
                children: 'children',
                hasChildren: 'hasChildren',
              }"
            ></el-tree>
          </el-form-item>
        </div>
        <!-- <div class="rk">
          <el-form-item label="备注">
            <el-input clearable v-model="addForm.remark" type="textarea" placeholder="请输入内容" />
          </el-form-item>
        </div> -->
        <div class="rk">
          <el-form-item label="角色描述">
            <el-input
              clearable
              v-model="addForm.remark"
              type="textarea"
              placeholder="请输入内容"
            />
          </el-form-item>
        </div>
      </el-form>
    </p-dialog>
    <!-- 分配角色数据权限对话框 -->
    <p-dialog
      :title="state.title"
      v-model="state.openDataScope"
      width="500px"
      @ok="submitDataScope"
      @close="close"
      append-to-body
    >
      <el-form :model="form" label-width="80px">
        <el-form-item label="角色名称">
          <el-input clearable v-model="addForm.roleName" :disabled="true" />
        </el-form-item>
        <!-- <el-form-item label="权限字符">
          <el-input clearable v-model="addForm.roleKey" :disabled="true" />
        </el-form-item> -->
        <el-form-item label="权限范围">
          <el-select
            v-model="addForm.dataScope"
            @change="dataScopeSelectChange"
          >
            <el-option
              v-for="item in dataScopeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据权限" v-show="addForm.dataScope == 2">
          <el-checkbox
            v-model="addForm.deptExpand"
            @change="handleCheckedTreeExpand($event, 'dept')"
            >展开/折叠</el-checkbox
          >
          <el-checkbox
            v-model="addForm.deptNodeAll"
            @change="handleCheckedTreeNodeAll($event, 'dept')"
            >全选/全不选</el-checkbox
          >
          <el-checkbox
            v-model="addForm.deptCheckStrictly"
            @change="handleCheckedTreeConnect($event, 'dept')"
            >父子联动</el-checkbox
          >
          <el-tree
            class="tree-border"
            :data="deptOptions"
            show-checkbox
            default-expand-all
            ref="deptRef"
            node-key="id"
            :check-strictly="!addForm.deptCheckStrictly"
            empty-text="加载中，请稍候"
            :props="{ label: 'label', children: 'children' }"
          ></el-tree>
        </el-form-item>
      </el-form>
    </p-dialog>
  </div>
</template>
<style scoped lang="scss">
.rk ::v-deep .el-form-item {
  width: 100% !important;
}
.tree-border {
  width: 100%;
}
</style>
